#ifndef __WIZ_DATATYPE_RECURNODE_HPP__SHANHAOBO_19800429__
#define __WIZ_DATATYPE_RECURNODE_HPP__SHANHAOBO_19800429__

#include "../Base/WizBase.hpp"
#include "../Core/Container/WizDataTypeArray.hpp"

namespace Wiz
{
    namespace RecurNode
    {
        template <class DerivedT, class BaseT>
        struct Type : public BaseT
        {
            /// for DerivedT
            typedef Type            tSuper;

            typedef DerivedT        tDerived;
            typedef tDerived*       tDerivedPtr;

            typedef BaseT           tBase;
            typedef tBase*          tBasePtr;

        public:
            tDerivedPtr             m_ParentPtr;
            tDerivedPtr             m_ChildPtr;
            tDerivedPtr             m_SiblingPtr;

        public:
            Type() : m_ChildPtr(WIZ_NULLPTR), m_ParentPtr(WIZ_NULLPTR), m_SiblingPtr(WIZ_NULLPTR), tBase()
            {

            }
        public:
            ::Wiz::Void::Type       AddChild(tDerivedPtr ChildPtr)
            {
                if (::Wiz::NotValid(ChildPtr))
                {
                    return;
                }

                if (::Wiz::IsValidPtr(m_ChildPtr))
                {
                    ChildPtr->m_SiblingPtr = m_ChildPtr->m_SiblingPtr;
                }

                m_ChildPtr = ChildPtr;
            }

            template<class FuncT>
            tDerivedPtr   FindChildIf(tDerivedPtr ComparePtr)
            {
                FuncT Func;
                tDerivedPtr ChildPtr = m_ChildPtr;
                while (::Wiz::IsValidPtr(ChildPtr))
                {
                    if (Func(ChildPtr, ComparePtr))
                    {
                        return ChildPtr;
                    }
                    ChildPtr = ChildPtr->m_SiblingPtr;
                }

                return WIZ_NULLPTR;
            }


            template<class FuncT>
            tDerivedPtr   RemoveChildIf(tDerivedPtr ComparePtr)
            {
                FuncT Func;
                WIZ_ASSERT(::Wiz::NotValidPtr(m_ParentPtr));
                tDerivedPtr PreChildPtr = WIZ_NULLPTR;
                tDerivedPtr ChildPtr = m_ChildPtr;
                while (::Wiz::IsValidPtr(ChildPtr))
                {
                    if (Func(ChildPtr, ComparePtr))
                    {
                        if (::Wiz::NotValidPtr(PreChildPtr))
                        {
                            m_ParentPtr->m_ChildPtr = ChildPtr->m_SiblingPtr;
                        }
                        else
                        {
                            PreChildPtr->m_SiblingPtr = ChildPtr->m_SiblingPtr;
                        }
                        return ChildPtr;
                    }
                    PreChildPtr = ChildPtr;
                    ChildPtr = ChildPtr->m_SiblingPtr;
                }

                return WIZ_NULLPTR;
            }

            tDerivedPtr   RemoveChild(tDerivedPtr ComparePtr)
            {
                WIZ_ASSERT(::Wiz::NotValidPtr(m_ParentPtr));
                tDerivedPtr PreChildPtr = WIZ_NULLPTR;
                tDerivedPtr ChildPtr = m_ChildPtr;
                while (::Wiz::IsValidPtr(ChildPtr))
                {
                    if (ChildPtr == ComparePtr)
                    {
                        if (::Wiz::NotValidPtr(PreChildPtr))
                        {
                            m_ParentPtr->m_ChildPtr = ChildPtr->m_SiblingPtr;
                        }
                        else
                        {
                            PreChildPtr->m_SiblingPtr = ChildPtr->m_SiblingPtr;
                        }
                        return ChildPtr;
                    }
                    PreChildPtr = ChildPtr;
                    ChildPtr = ChildPtr->m_SiblingPtr;
                }

                return WIZ_NULLPTR;
            }
        };
    } /// end of namespace RecurNode
} /// end of namespace Wiz

#endif /*__WIZ_DATATYPE_RECURNODE_HPP__SHANHAOBO_19800429__*/
